package com.gradumate.server.alfresco;

import java.util.ArrayList;
import java.util.logging.Logger;

import com.gradumate.server.dao.Gebruiker_DAO;
import com.gradumate.shared.ContentItem;
import com.gradumate.shared.Gebruiker;

/**
 * Classe die verschillende ArrayLists ophaald met Gebruikers. Deze worden
 * onderverdeeld in 2 verschillende.
 * 
 * 1. Functie met afstudeerverzoeken van Gebruikers word bepaald door te controleren in de map
 * 2. Functie met afstudeervoorstellen van Gebruikers die nog moeten worden beoordeeld, deze
 * staan in de map
 * 
 * @author HugoZonderland
 * 
 */
public class FolderContent {

	// ArrayList met alle studenten
	private ArrayList<Gebruiker> studenten;

	// Gebruiker DataStore
	private Gebruiker_DAO gebruikerDS = new Gebruiker_DAO();
	
	// Logger
	private final Logger log = Logger.getLogger(FolderContent.class.getName());

	/**
	 * Constructor
	 */
	public FolderContent() {
		studenten = gebruikerDS.getStudenten();
	}
	
	/**
	 * Haalt alle afstudeervoorstellen op. Deze worden bepaald wanneer er een
	 * word document of PDF in de map In Behandeling op Alfresco staat.
	 * 
	 * @return ArrayList<Gebruiker> van mappen van studenten waar afstudeervoorstellen in staan.
	 */
	public ArrayList<Gebruiker> getOnbeoordeeldeAfstudeerVoorstellen() {
		return getFolderContents("In behandeling");
	}

	/**
	 * Haalt alle afstudeerverzoeken op Deze worden bepaald wanneer er in een
	 * Word of PFD in de map Concept op Alfresco staat.
	 * 
	 * @return ArrayList<Gebruiker> van mappen van studenten waar afstudeerverzoeken instaan.
	 */
	public ArrayList<Gebruiker> getOnbeoordeeldeAfstudeerVerzoeken() {
		return getFolderContents("Concept");
	}

	/**
	 * Haalt alle namen van studenten op die goed gekeurde afstudeervoorstellen hebben
	 * 
	 * @return ArrayList<Gebruiker> met studenten met goedgekeurde afstudeervoorstellen
	 */
	public ArrayList<Gebruiker> getGoedGekeurdeAfstudeerVoorstellen() {
		return getFolderContents("Goedgekeurd");
	}
	
	/**
	 * Haalt alle namen van studenten op die afgekeurde afstudeervoorstellen hebben
	 * 
	 * @return ArrayList<Gebruiker> met studenten die afgekeurde afstudeervoorstellen hebben
	 */
	public ArrayList<Gebruiker> getAfgekeurdeAfstudeerVoorstellen() {
		return getFolderContents("Afgekeurd");
	}
	
	/**
	 * Bepaald of er een goedgekeurd afstudeervoorstel is.
	 * 
	 * @return true wanneer er een of meerdere documenten instaan.
	 */
	public boolean hasAfstudeerVoorstelGoedgekeurd() {
		return !getFolderContents("Goedgekeurd").isEmpty();
	}

	/**
	 * Een voorstel is afgekeurd wanneer: 
	 * 1. Er geen voorstel meer inbehandeling
	 * is. 
	 * 2. Het verzoek is goed gekeurd. 
	 * 3. Er geen goedgekeurd voorstel is.
	 * 4. Er tenminste 1 document in de map Afgekeurd staat
	 * 
	 * @return true wanneer er een of meerdere documeten instaan en er nog geen
	 *         goedgekeurd voorstel is ingediend
	 */
	public boolean hasAfstudeerVoorstelAfgekeurd() {
		return 
		/* 1 */getOnbeoordeeldeAfstudeerVoorstellen().isEmpty()
		/* 2 */&& !getOnbeoordeeldeAfstudeerVerzoeken().isEmpty()
		/* 3 */&& !hasAfstudeerVoorstelGoedgekeurd()
		/* 4 */&& !getFolderContents("Afgekeurd").isEmpty();
	}
	
	/**
	 * Stuurt het totaal aantal afstudeerverzoeken terug
	 * @return int met totaal aantal afstudeerverzoeken
	 */
	public int getTotaalAantalAfstudeerVerzoeken() {
		return getTotaalAantalContentItems() - getTotaalAantalOnBeoordeeldeAfstudeerVoorstellen();
	}

	/**
	 * Geeft het aantal nog te beoordelen afstudeerverzoeken terug
	 * @return int met aantal
	 */
	public int getTotaalAantalOnbeoordeeldeAfstudeerVerzoeken() {
		return getOnbeoordeeldeAfstudeerVerzoeken().size();
	}
	
	/**
	 * Geeft het totaal aantal goedgekeurde verzoeken terug.
	 * @return int met aantal goedgekeurde verzoeken
	 */
	public int getTotaalAantalBeoordeeldeAfstudeerVerzoeken() {
		return getGoedGekeurdeAfstudeerVoorstellen().size();
	}
	
	/**
	 * Geeft het totaal aantal goed gekeurde afstudeerverzoeken terug
	 * @return int met aantal goed gekeurde afstudeerverzoeken
	 */
	public int getTotaalAantalGoedGekeurdeAfstudeerVerzoeken() {
		return getTotaalAantalGoedGekeurdeAfstudeerVoorstellen() + getTotaalAantalOnBeoordeeldeAfstudeerVoorstellen();
	}
	
	/**
	 * Haalt het aantal afgekeurde afstudeeerverzoeken op
	 * @return int met totaal aantal afstudeerverzoeken
	 */
	public int getTotaalAantalAfgekeurdeAfstudeerVerzoeken() {

		int totaalafgekeurdeafstudeerverzoeken = 0;
		
		// Door alle studenten heel lopen
		for (Gebruiker student : studenten) {
			// Site bepalen
			String site = student.getFaculteit().toLowerCase();
			// Pad bepalenn aan de hand van de informatie die bekend is van de student.
			String pad = student.getInstituut() + "/" + student.getOpleiding().get(0) + "/" + student.getInschrijfjaar() + "/" + student.getGebruikerEmail() + "/";

			// Instance van ContentBeheer aanmaken om de map inhoud te
			// bepalen
			ContentBeheer contentBeheer = new ContentBeheer();

			// Map inhoud ophalen
			ArrayList<ContentItem> afgekeurdeitems = contentBeheer.getSiteContent(site, pad + "Afgekeurd");
			ArrayList<ContentItem> conceptitems = contentBeheer.getSiteContent(site, pad + "Concept");
		
			// Een verzoek is afgekeurd wanneer
			// Er 1 of meerdere afgekeurd voorstel zijn en 0 of 1 concepten
			if ((afgekeurdeitems != null && conceptitems != null) && (afgekeurdeitems.size() > 0 && (conceptitems.isEmpty() || !conceptitems.isEmpty()))) {
				totaalafgekeurdeafstudeerverzoeken++;
			}
		}
		
		return totaalafgekeurdeafstudeerverzoeken;
	}
	
	/**
	 * Geeft het aantal ingediende afstudeervoorstellen op
	 * @return int met aantal
	 */
	public int getTotaalAantalAfstudeerVoorstellen() {
		return getTotaalAantalOnBeoordeeldeAfstudeerVoorstellen() + 
		getTotaalAantalGoedGekeurdeAfstudeerVoorstellen() +
		getTotaalAantalAfgekeurdeAfstudeerVoorstellen();
		//getTotaalAantalContentItems() - getTotaalAantalOnbeoordeeldeAfstudeerVerzoeken() -
		//getTotaalAantalAfgekeurdeAfstudeerVerzoeken();
	}
	
	/**
	 * Geeft het aantal onbeoordeelde afstudeervoorstellen terug
	 * @return int met aantal afstudeervoorstellen
	 */
	public int getTotaalAantalOnBeoordeeldeAfstudeerVoorstellen() {
		return getOnbeoordeeldeAfstudeerVoorstellen().size();
	}
	
	/**
	 * Geeft het aantal goed gekeurde afstudeervoorstellen terug
	 * @return int met aantal goed gekeurde afstudeervoorstellen
	 */
	public int getTotaalAantalGoedGekeurdeAfstudeerVoorstellen() {
		return getGoedGekeurdeAfstudeerVoorstellen().size();
	}
	
	/**
	 * Haalt het totaal aantal afgekeurde afstudeervoorstellen op
	 * @return int met aantal afstudeervoorstellen
	 */
	public int getTotaalAantalAfgekeurdeAfstudeerVoorstellen() {
		
		int totaalafgekeurdeafstudeervoorstellen = 0;
		
		// Door alle studenten heel lopen
		for (Gebruiker student : studenten) {
			// Site bepalen
			String site = student.getFaculteit().toLowerCase();
			// Pad bepalenn aan de hand van de informatie die bekend is van de student.
			String pad = student.getInstituut() + "/" + student.getOpleiding().get(0) + "/" + student.getInschrijfjaar() + "/" + student.getGebruikerEmail() + "/";

			// Instance van ContentBeheer aanmaken om de map inhoud te
			// bepalen
			ContentBeheer contentBeheer = new ContentBeheer();

			// Map inhoud ophalen
			ArrayList<ContentItem> afgekeurdeitems = contentBeheer.getSiteContent(site, pad + "Afgekeurd");
			ArrayList<ContentItem> conceptitems = contentBeheer.getSiteContent(site, pad + "In behandeling");
		
			// Een voorstel is afgekeurd wanneer
			// Er 1 of meerdere afgekeurd voorstel zijn en 0 of 1 in behandeling
			if ((afgekeurdeitems != null && conceptitems != null) && (afgekeurdeitems.size() > 0 && (conceptitems.isEmpty() || !conceptitems.isEmpty()))) {
				totaalafgekeurdeafstudeervoorstellen++;
			}
		}
		return totaalafgekeurdeafstudeervoorstellen;
	}
	
	/**
	 * Haalt alle afgekeurde ContentItems van de student op
	 * @param Gebruiker student
	 * @return ArrayList<ContentItem>
	 */
	public ArrayList<ContentItem> getStudentAfgekeurdVoorstellen(Gebruiker student) {
		return getStudentContentInFolder(student, "Afgekeurd");
	}
	
	/**
	 * Haalt alle afgekeurde ContentItems van de student op
	 * @param Gebruiker student
	 * @return ArrayList<ContentItem>
	 */
	public ArrayList<ContentItem> getStudentGoedgekeurdeVoorstellen(Gebruiker student) {
		return getStudentContentInFolder(student, "Goedgekeurd");
	}
	
	/**
	 * Haalt alle afgekeurde ContentItems van de student op
	 * @param Gebruiker student
	 * @return ArrayList<ContentItem>
	 */
	public ArrayList<ContentItem> getStudentConceptVoorstellen(Gebruiker student) {
		return getStudentContentInFolder(student, "Concept");
	}
	
	/**
	 * Haalt alle afgekeurde ContentItems van de student op
	 * @param Gebruiker student
	 * @return ArrayList<ContentItem>
	 */
	public ArrayList<ContentItem> getStudentInBehandelingVoorstellen(Gebruiker student) {
		return getStudentContentInFolder(student, "In behandeling");
	}

	/**
	 * Haalt alle mappen op en controleerd of er een document in de opgegeven map
	 * bevind. Wanneer deze niet leeg is word deze aan de return array
	 * toegevoegd en teruggeven.
	 * 
	 * @param String
	 *            folder map waarin gezocht word
	 * @return ArrayList<String> met mappen waar een document in de map staat.
	 */
	private ArrayList<Gebruiker> getFolderContents(String folder) {
		
		log.info("Foldercontent bepalen voor " + folder);
		
		// Return met Gebruikers waarvan het verzoek/voorstel nog moet worden beoordeeld.
		ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>();
		
		for (Gebruiker student : studenten) {
			// Site bepalen
			String site = student.getFaculteit().toLowerCase();
			// Pad bepalenn aan de hand van de informatie die bekend is van de student.
			String pad = student.getInstituut() + "/" + student.getOpleiding().get(0) + "/" + student.getInschrijfjaar() + "/" + student.getGebruikerEmail() + "/";

			// Instance van ContentBeheer aanmaken om de map inhoud te
			// bepalen
			ContentBeheer contentBeheer = new ContentBeheer();

			// Map inhoud ophalen
			ArrayList<ContentItem> siteContentItems = contentBeheer.getSiteContent(site, pad + folder);
			
			// Controleerd of de inhoud van de site niet leeg is.
			if (siteContentItems != null && !siteContentItems.isEmpty()) {
				// Wanneer de map concept word behandeld moet de StoreID gezet worden in het Student object
				if (folder.equals("Concept")) {
					student.setAfstudeervoorstelItemID(siteContentItems.get(0).getContentID());
					gebruikerDS.updateGebruiker(student);
				}
				// Student toevoegen aan de array.
				gebruikers.add(student);
			}
		}
		// afstudeervoorstellen teruggeven.
		return gebruikers;
	}
	
	/**
	 * Haalt het totale aantal afstudeerverzoeken/voorstellen op.
	 * @return int met totaal aantal contentitems
	 */
	public int getTotaalAantalContentItems() {
	
		int totaalcontentitems = 0;
		
		// Te doorzoeken folders defineren
		ArrayList<String> folders = new ArrayList<String>();
		folders.add("Concept");
		folders.add("Afgekeurd");
		folders.add("Goedgekeurd");
		folders.add("In behandeling");
	
		for (String folder: folders) {
			totaalcontentitems += getItemsInFolder(folder);
		}
		
		return totaalcontentitems;
	}
	
	/**
	 * Telt het aantal contentitems in de gegeven folder van alle studenten
	 * @param folder
	 * @return int met aantal in die map
	 */
	private int getItemsInFolder(String folder) {
		
		int aantal = 0;
	
		// Door alle studenten heel lopen
		for (Gebruiker student : studenten) {

			// Map inhoud ophalen
			ArrayList<ContentItem> items = getStudentContentInFolder(student, folder);
			
			if (items != null && !items.isEmpty()) {
				aantal += items.size();
			}
		}
		
		return aantal;
	}
	
	/**
	 * Haalt alle contentitems van 1 specifieke map van de student op
	 * @param Gebruiker student van de map
	 * @param String folder 
	 * @return ArrayList met contentitems
	 */
	private ArrayList<ContentItem> getStudentContentInFolder(Gebruiker student, String folder) {
	
		// Contentitems
		ArrayList<ContentItem> contentitems = new ArrayList<ContentItem>();
		
		if (student != null && folder != null) {
			// Site bepalen
			String site = student.getFaculteit().toLowerCase();
			
			// Pad bepalenn aan de hand van de informatie die bekend is van de student.
			String pad = student.getInstituut() + "/" + student.getOpleiding().get(0) + "/" + student.getInschrijfjaar() + "/" + student.getGebruikerEmail() + "/";
	
			// Instance van ContentBeheer aanmaken om de map inhoud te bepalen
			ContentBeheer contentBeheer = new ContentBeheer();
	
			// Map inhoud ophalen
			contentitems = contentBeheer.getSiteContent(site, pad + folder);
		}
		
		return contentitems;
	}
}
